home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <xview/xview.h>
- #include <xview/canvas.h>
- #include <xview/panel.h>
- #include <xview/xv_xrect.h>
- #include <xview/notice.h>
- #include <X11/Xlib.h>
- #include <strings.h>
- #include "copyright.h"
-
- #include "white.xbm"
- #include "gray.xbm"
-
- #define HEIGHT 20 /* of game */
- #define WIDTH 20
- #define SWIDTH 40 /* of cells */
- #define SHEIGHT 40
- #define BWIDTH 14 /* of border */
- #define BHEIGHT 14
-
- void keyboard();
- void draw_screen();
- void DrawCell();
- void newscreen();
- unsigned long getcolor();
- int quit();
-
- int myarr[HEIGHT][WIDTH];
- int height;
- int width;
- int showmove;
- int clearscreen = 0;
- int update_x, update_y;
- char colorname[4][64] =
- {
- "notused","red","blue", "yellow"
- };
- Pixmap patpix[4];
- Pixmap showpix[2];
- Colormap cmap;
- Display *display;
- Window xwin;
- Xv_Window xv_win;
- GC gc;
- int screen;
- unsigned long foreground, background;
- int mono = 0;
-
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i = 1;
- Frame frame;
- Canvas canvas;
- Panel panel;
-
- void canvas_proc();
- void event_proc();
- void clear_proc();
- void width_proc();
- void height_proc();
- void show_proc();
- Xv_opaque help_proc();
- Xv_opaque quit_proc();
- void startup();
-
- xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
-
- height = 5;
- width = 5;
- while (i < argc && argv[i][0] == '-') {
- if (strcmp(argv[i], "-height") == 0) {
- height = atoi(argv[i+1]);
- i++;
- }
- else if (strcmp(argv[i], "-width") == 0) {
- width = atoi(argv[i+1]);
- i++;
- }
- else if (strcmp(argv[i], "-color1") == 0) {
- sprintf(colorname[1], argv[i+1]);
- i++;
- }
- else if (strcmp(argv[i], "-color2") == 0) {
- sprintf(colorname[2], argv[i+1]);
- i++;
- }
- else if (strcmp(argv[i], "-color3") == 0) {
- sprintf(colorname[3], argv[i+1]);
- i++;
- }
- else if (strcmp(argv[i], "-mono") == 0) {
- mono = 1;
- }
- else if (strcmp(argv[i], "-square") == 0) {
- width = atoi(argv[i+1]);
- height = width;
- i++;
- }
- i++;
- }
- width = (width > WIDTH) ? WIDTH : width;
- height = (height > HEIGHT) ? HEIGHT : height;
-
-
- frame = (Frame)xv_create(NULL, FRAME,
- FRAME_LABEL, argv[0],
- XV_WIDTH, 140 + width*SWIDTH,
- XV_HEIGHT, height*SHEIGHT + 2*BHEIGHT + 57,
- NULL);
-
- panel = xv_create(frame, PANEL,
- XV_HEIGHT, 55,
- NULL);
-
- (void)xv_create(panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Quit",
- PANEL_NOTIFY_PROC, quit_proc,
- NULL);
-
- (void)xv_create(panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Clear",
- PANEL_NOTIFY_PROC, clear_proc,
- NULL);
-
- (void)xv_create(panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Show Moves",
- PANEL_NOTIFY_PROC, show_proc,
- NULL);
-
- (void)xv_create(panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Help",
- PANEL_NOTIFY_PROC, help_proc,
- NULL);
-
- (void)xv_create(panel, PANEL_NUMERIC_TEXT,
- PANEL_LABEL_STRING, "Width",
- PANEL_VALUE, width,
- PANEL_NEXT_ROW, -1,
- PANEL_MIN_VALUE, 1,
- PANEL_MAX_VALUE, 20,
- PANEL_VALUE_DISPLAY_LENGTH, 1,
- PANEL_NOTIFY_PROC, width_proc,
- NULL);
-
- (void)xv_create(panel, PANEL_NUMERIC_TEXT,
- PANEL_LABEL_STRING, "Height",
- PANEL_VALUE, height,
- PANEL_MIN_VALUE, 1,
- PANEL_MAX_VALUE, 20,
- PANEL_VALUE_DISPLAY_LENGTH, 1,
- PANEL_NOTIFY_PROC, height_proc,
- NULL);
-
- canvas = xv_create(frame, CANVAS,
- CANVAS_REPAINT_PROC, canvas_proc,
- CANVAS_X_PAINT_WINDOW, TRUE,
- CANVAS_AUTO_EXPAND, TRUE,
- CANVAS_AUTO_SHRINK, TRUE,
- NULL);
- window_fit(frame);
-
- startup(frame, canvas);
- xv_set(canvas_paint_window(canvas),
- WIN_EVENT_PROC, event_proc,
- WIN_CONSUME_EVENTS,
- KBD_DONE, KBD_USE, LOC_DRAG, LOC_MOVE, LOC_WINENTER,
- LOC_WINEXIT, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
- NULL,
- NULL);
- update_x = -1;
- xv_main_loop(frame);
- }
-
- InArray(x,y)
- {
- return ((x >= 0 && x < width) && (y >= 0 && y < height)) ? 1 : 0;
- }
-
- mymarkcell(x, y)
- int x;
- int y;
-
- {
- if (InArray(x,y)) {
- myarr[x][y] = 3 - myarr[x][y];
- }
- if (InArray(x-1,y)) {
- myarr[x-1][y] = (2 + myarr[x-1][y])%4;
- }
- if (InArray(x+1,y)) {
- myarr[x+1][y] = (2 + myarr[x+1][y])%4;
- }
- if (InArray(x,y+1)) {
- myarr[x][y+1] = (2 + myarr[x][y+1])%4;
- }
- if (InArray(x,y-1)) {
- myarr[x][y-1] = (2 + myarr[x][y-1])%4;
- }
- }
-
- void clear_proc(item, event)
- Panel_item item;
- Event *event;
- {
- clearscreen = 1;
- newscreen();
- canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
- xwin, (Xv_xrectlist *)NULL);
-
- }
-
- void width_proc(item, event)
- Panel_item item;
- Event *event;
- {
- width = xv_get(item, PANEL_VALUE);
- clearscreen = 1;
- newscreen();
- canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
- xwin, (Xv_xrectlist *)NULL);
-
- }
-
- void height_proc(item, event)
- Panel_item item;
- Event *event;
- {
- height = xv_get(item, PANEL_VALUE);
- clearscreen = 1;
- newscreen();
- canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
- xwin, (Xv_xrectlist *)NULL);
-
- }
-
- void show_proc(item, event)
- Panel_item item;
- Event *event;
- {
- showmove = 1 - showmove;
- clearscreen = 1;
- if(showmove) { /* show the '.' on clicked squares */
- patpix[1] = showpix[0];
- patpix[3] = showpix[1];
- }
- else {
- patpix[1] = patpix[0];
- patpix[3] = patpix[2];
- }
- canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
- xwin, (Xv_xrectlist *)NULL);
-
- }
-
- Xv_opaque help_proc(item, event)
- Panel_item item;
- Event *event;
- {
- int result;
- Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
-
- result = notice_prompt(panel, NULL,
- NOTICE_MESSAGE_STRINGS,
- "Xquinto is a puzzle on a rectangular board. Clicking on",
- "any square reverses its color, and that of its neighbors",
- "that share an edge (not the diagonal ones). The object,",
- "starting from a red board, is to color each square blue.",
- " ",
- "The 5 by 5 puzzle can be solved!",
- " ",
- "Dev Joneja, dj7@cunixf.cc.columbia.edu",
- NULL,
- NOTICE_BUTTON_YES, "OK",
- NULL);
- if (result == NOTICE_YES) return;
- }
-
-
- Xv_opaque quit_proc(item, event)
- Panel_item item;
- Event *event;
- {
- int result;
- Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
-
- result = notice_prompt(panel, NULL,
- NOTICE_MESSAGE_STRINGS,
- "What... already?", NULL,
- NOTICE_BUTTON_YES, "jah",
- NOTICE_BUTTON_NO, "no mon",
- NULL);
- if (result == NOTICE_YES) quit();
- if (result == NOTICE_NO) return;
- }
-
- void event_proc(window, event)
- Xv_window window;
- Event *event;
- {
- static int x,y;
-
- if (event_is_ascii(event)) {
- if (event_is_down(event))
- keyboard(event_action(event));
- }
- else
- switch (event_action(event)) {
- case ACTION_SELECT:
- case MS_LEFT:
- case ACTION_ADJUST:
- case MS_MIDDLE:
- case ACTION_MENU:
- case MS_RIGHT:
- if (event_is_down(event)) {
- x = (event_x(event)-BWIDTH)/SWIDTH;
- y = (event_y(event)-BHEIGHT)/SHEIGHT;
- if (InArray(x,y)) {
- mymarkcell(x,y);
- update_x = x;
- update_y = y;
- }
- }
- else return;
- break;
- default:
- return;
- }
- canvas_proc((Canvas)NULL, window, (Display*)xv_get(window, XV_DISPLAY),
- xv_get(window, XV_XID), (Xv_xrectlist *)NULL);
- }
-
- void canvas_proc(canvas, pwin, dpy, x_win, xrects)
- Canvas canvas;
- Xv_Window pwin;
- Display *dpy;
- Window x_win;
- Xv_xrectlist *xrects;
- {
- if (clearscreen) {
- XClearWindow(dpy, x_win);
- clearscreen = 0;
- }
- draw_screen();
- }
-
- void newscreen()
- {
- int i,j,k;
- int x,y;
-
- for(i=0; i < width; i++)
- for(j=0; j < height; j++)
- myarr[i][j] = 0;
- }
-
-
- int quit()
- {
- exit(1);
- }
-
-
- void startup(frame, canvas)
- Frame frame;
- Canvas canvas;
- {
- int i;
- int depth;
- char *pixstr = ".";
- unsigned long patbg, patfg;
- char fontname[80];
- XFontStruct *xfontinfo;
-
- display = (Display *)xv_get(frame, XV_DISPLAY);
- screen = DefaultScreen(display);
- depth = DefaultDepth(display,screen);
- if (depth < 2) mono = 1;
- gc = DefaultGC(display, screen);
- xv_win = canvas_paint_window(canvas);
- xwin = xv_get(xv_win, XV_XID);
-
- /* default pixel values */
- cmap = DefaultColormap(display, screen);
-
- background = WhitePixel(display, screen);
- foreground = BlackPixel(display, screen);
- XSetBackground(display, gc, background);
- XSetForeground(display, gc, foreground);
-
- sprintf(fontname, "8x13bold");
- if((xfontinfo = XLoadQueryFont(display,fontname)) == NULL)
- {
- fprintf(stderr,"Can't find font '%s'\n",fontname);
- xfontinfo = XQueryFont(display,XGContextFromGC(gc));
- }
- XSetFont(display,gc,xfontinfo->fid);
-
- if(!mono) patbg = getcolor(colorname[1] ,background);
- patpix[0] = XCreatePixmapFromBitmapData(display,xwin,
- gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
- patbg, depth);
- showpix[0] = XCreatePixmapFromBitmapData(display,xwin,
- gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
- patbg, depth);
- if(!mono) patbg = getcolor(colorname[2],background);
- patpix[2] = XCreatePixmapFromBitmapData(display,xwin,
- white_xbm_bits,SWIDTH,SHEIGHT,foreground,
- patbg, depth);
- showpix[1] = XCreatePixmapFromBitmapData(display,xwin,
- white_xbm_bits,SWIDTH,SHEIGHT,foreground,
- patbg, depth);
- /* put the '.' on the showpix */
- patfg = getcolor(colorname[3],foreground);
- XSetForeground(display, gc, patfg);
- XDrawString(display,showpix[0],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
- XDrawString(display,showpix[1],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
- XSetForeground(display, gc, foreground);
-
- if(showmove) { /* show the '.' on clicked squares */
- patpix[1] = showpix[0];
- patpix[3] = showpix[1];
- }
- else {
- patpix[1] = patpix[0];
- patpix[3] = patpix[2];
- }
- }
-
- unsigned long getcolor(s,monocolor)
- char *s;
- unsigned long monocolor;
- {
- XColor exact_def;
-
- if(!mono) {
- XParseColor(display, cmap, s, &exact_def);
- XAllocColor(display, cmap, &exact_def);
- return exact_def.pixel;
- }
- else
- return monocolor;
- }
-
- /* update_x update_y are used for efficiency in playing: instead of
- repainting the whole screen in case of a move, it only paints the
- adjoining cells.
- */
- void draw_screen()
- {
- int i, j;
-
- if (update_x > -1) {
- for ( i = update_y - 1; i < update_y + 2; i++)
- for (j = update_x - 1; j < update_x + 2; j++)
- DrawCell(j, i);
- update_x = update_y = -1;
- }
- else {
- for (i = 0; i < height; i++)
- for (j = 0; j < width; j++)
- DrawCell(j,i);
- DrawShadow(0, 0, width*SWIDTH + 2*BWIDTH - 1,
- height*SHEIGHT + 2*BHEIGHT - 1, 3);
- DrawShadow(BWIDTH-4, BHEIGHT-4, BWIDTH + width*SWIDTH + 3,
- BHEIGHT + height*SHEIGHT +3, -3);
- }
- }
-
-
- void keyboard(c)
- int c;
- {
- switch(c){
- case 'q':
- quit();
- break;
- case 'c':
- break;
- default:
- return;
- }
- newscreen();
- clearscreen = 1;
- }
-
- void DrawCell(x, y)
- int x;
- int y;
-
- {
- int val;
-
- if(InArray(x,y)) {
- val = myarr[x][y];
- XCopyArea(display, patpix[val], xwin, gc, 0, 0, SWIDTH, SHEIGHT,
- x*SWIDTH + BWIDTH ,y*SHEIGHT + BHEIGHT);
- }
- }
-
- DrawShadow(x1,y1,x2,y2,dir)
- int x1;
- int y1;
- int x2;
- int y2;
- int dir;
- {
- int i;
- GC highlightgc,shadowgc;
- unsigned long patbg, patfg;
-
- highlightgc = XCreateGC(display, xwin, 0, 0);
- shadowgc = XCreateGC(display, xwin, 0, 0);
- if(!mono) {
- patbg = getcolor("gray", background);
- patfg = getcolor("black", foreground);
- }
-
- if(dir < 0) {
- XSetForeground(display, highlightgc, patfg);
- XSetForeground(display, shadowgc, patbg);
- dir = -dir;
- }
- else {
- XSetForeground(display, shadowgc, patfg);
- XSetForeground(display, highlightgc, patbg);
- }
-
- for(i=0; i < dir; i++) {
- XDrawLine(display,xwin,highlightgc,x1,y1,x1,y2);
- XDrawLine(display,xwin,shadowgc,x1,y2,x2,y2);
- XDrawLine(display,xwin,shadowgc,x2,y1,x2,y2);
- XDrawLine(display,xwin,highlightgc,x1,y1,x2,y1);
- x1++; x2--; y1++; y2--;
- }
- }
-